package com.dux.commons.utils;

import java.io.ByteArrayOutputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.util.zip.Deflater;  
import java.util.zip.DeflaterOutputStream;  
import java.util.zip.Inflater;  
import java.util.zip.InflaterInputStream;  
  
/** 
 * ZLib压缩工具 
 *  
 * @author 杜祥 
 * @date 2012-09-11
 */  
public final class ZLibUtils
{  
  
    /** 
     * 压缩 
     *  
     * @param data 
     *            待压缩数据 
     * @return byte[] 压缩后的数据 
     */  
    public static byte[] compress(byte[] data)
    {  
        byte[] output = new byte[0];  
        
        Deflater compresser = new Deflater();  
  
        compresser.reset();  
        compresser.setInput(data);  
        compresser.finish();  
        ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);  
        try
        {  
            byte[] buf = new byte[1024];  
            while (!compresser.finished()) 
            {  
                int i = compresser.deflate(buf);  
                bos.write(buf, 0, i);  
            }  
            output = bos.toByteArray();  
        } 
        catch (Exception e)
        {  
            output = data;  
            e.printStackTrace();  
        } 
        finally 
        {  
            try 
            {  
                bos.close();  
            } 
            catch (IOException e)
            {  
                e.printStackTrace();  
            }  
        }  
        compresser.end();  
        return output;  
    }  
  
    /** 
     * 压缩 
     *  
     * @param data 
     *            待压缩数据 
     *  
     * @param os 
     *            输出流 
     */  
    public static void compress(byte[] data, OutputStream os) 
    {  
        DeflaterOutputStream dos = new DeflaterOutputStream(os);  
  
        try 
        {  
            dos.write(data, 0, data.length);  
  
            dos.finish();  
  
            dos.flush();  
        } 
        catch (IOException e)
        {  
            e.printStackTrace();  
        }  
    }  
  
    /** 
     * 解压缩 
     *  
     * @param data 
     *            待压缩的数据 
     * @return byte[] 解压缩后的数据 
     */  
    public static byte[] decompress(byte[] data)
    {  
        byte[] output = new byte[0];  
  
        Inflater decompresser = new Inflater();  
        decompresser.reset();  
        decompresser.setInput(data);  
  
        ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);  
        try 
        {  
            byte[] buf = new byte[1024];  
            while (!decompresser.finished()) 
            {  
                int i = decompresser.inflate(buf);  
                o.write(buf, 0, i);  
            }  
            output = o.toByteArray();  
        }
        catch (Exception e) 
        {  
            output = data;  
            e.printStackTrace();  
        }
        finally 
        {  
            try
            {  
                o.close();  
            } 
            catch (IOException e) 
            {  
                e.printStackTrace();  
            }  
        }  
        decompresser.end();  
        return output;  
    }  
  
    /** 
     * 解压缩 
     *  
     * @param is 
     *            输入流 
     * @return byte[] 解压缩后的数据 
     */  
    public static byte[] decompress(InputStream is)
    {  
        InflaterInputStream iis = new InflaterInputStream(is);  
        ByteArrayOutputStream o = new ByteArrayOutputStream(1024);  
        try
        {  
            int i = 1024;  
            byte[] buf = new byte[i];  
  
            while ((i = iis.read(buf, 0, i)) > 0)
            {  
                o.write(buf, 0, i);  
            }  
  
        } 
        catch (IOException e)
        {  
            e.printStackTrace();  
        }  
        return o.toByteArray();  
    }  
    
    public static void main(String[] args)
    {
    /*	System.err.println("字节压缩／解压缩测试");  
    	//String inputStr = "111110110010001000100010001001110011000100001000010000101110011001";
        String inputStr = "asdfghjklqwertyuiopzxcvbnm";  
        System.err.println("输入字符串:\t" + inputStr);  
        byte[] input = inputStr.getBytes();  
        System.err.println("输入字节长度:\t" + input.length);  
  
        byte[] data = ZLibUtils.compress(input);  
        System.err.println("压缩后字节长度:\t" + data.length);  
  
        byte[] output = ZLibUtils.decompress(data);  
        System.err.println("解压缩后字节长度:\t" + output.length);  
        String outputStr = new String(output);  
        System.err.println("输出字符串:\t" + outputStr); */
        
  /*      
        System.err.println("ByteBuffer字节压缩／解压缩测试");  
    	ByteBuffer buffer = ByteBuffer.allocate(28);
    	buffer.putInt(24);
    	buffer.putShort((short) 1);
    	buffer.putShort((short) 1000);
    	buffer.putLong(10000000);
    	buffer.putInt(234567);
    	buffer.putInt(7890);
    	buffer.putInt(2315);
        byte[] input1 = buffer.array();  
        System.err.println("输入字节长度:\t" + input1.length);  
   
        byte[] data1 = ZLibUtils.compress(input1);  
        System.err.println("压缩后字节长度:\t" + data1.length);  
   
        byte[] output1 = ZLibUtils.decompress(data1);  
        System.err.println("解压缩后字节长度:\t" + output1.length);*/
        
        
 /*       System.err.println("二进制字节压缩／解压缩测试");  
        StringBuilder string = new StringBuilder();
        string.append(Integer.toBinaryString(24));
        string.append(Integer.toBinaryString(1));
        string.append(Integer.toBinaryString(1000));
        string.append(Long.toBinaryString(10000000));
        string.append(Integer.toBinaryString(234567));
        string.append(Integer.toBinaryString(7890));
        string.append(Integer.toBinaryString(2315));
        byte[] input2 = string.toString().getBytes();  
        System.err.println("输入字节长度:\t" + input2.length);  
   
        byte[] data2 = ZLibUtils.compress(input2);  
        System.err.println("压缩后字节长度:\t" + data2.length);  
   
        byte[] output2 = ZLibUtils.decompress(data2);  
        System.err.println("解压缩后字节长度:\t" + output2.length);*/
  /*      
        
    	 System.err.println("ByteBuffer字节压缩／解压缩测试");  
     	ByteBuffer buffer = ByteBuffer.allocate(28);
     	buffer.putInt(24);
     	buffer.putShort((short) 1);
     	buffer.putShort((short) 1000);
     	buffer.putLong(10000000);
     	buffer.putInt(234567);
     	buffer.putInt(7890);
     	buffer.putInt(2315);
         byte[] input1 = buffer.array();  
         System.err.println("输入字节长度:\t" + input1.length);  
         long time = System.currentTimeMillis();
         byte[] data1 = null;
         for(int i = 0; i < 100000 ; i++)
         {
        	 data1 = ZLibUtils.compress(input1);  
         }
         System.err.println("小压缩" + (System.currentTimeMillis() - time) + "ms");
         long time1 = System.currentTimeMillis();;
         byte[] output1 = null;
         for(int i = 0; i < 100000 ; i++)
         {
        	 output1 = ZLibUtils.decompress(data1); 
         }
         System.err.println("小解压" + (System.currentTimeMillis() - time1) + "ms");
        
        System.err.println("大ByteBuffer字节压缩／解压缩测试");  
    	ByteBuffer buffer3 = ByteBuffer.allocate(4000);
    	int count = 0;
    	for(int i = 0 ; i < 1000; i++)
    	{
    		count += i;
    		buffer3.putInt(count);
    	}
        byte[] input3 = buffer3.array();  
        System.err.println("输入字节长度:\t" + input3.length);
        long time2 = System.currentTimeMillis();
        byte[] data3 = null;
        for(int i = 0; i < 100000 ; i++)
        {
        	data3 = ZLibUtils.compress(input3);  
           // System.err.println("压缩后字节长度:\t" + data3.length); 
        }
        System.err.println("大压缩" + (System.currentTimeMillis() - time2) + "ms");
        
        long time3 = System.currentTimeMillis();
        byte[] output3 = null;
        for(int i = 0; i < 100000 ; i++)
        {
        	output3 = ZLibUtils.decompress(data3);  
           // System.err.println("解压缩后字节长度:\t" + output3.length);
        }
        System.err.println("大解压" + (System.currentTimeMillis() - time3) + "ms");
       
        */
	}
}  
